package com.idroc.coelacanth.core.message;

import java.util.HashMap;
import java.util.Map;

import org.jboss.netty.channel.ChannelDownstreamHandler;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ChannelUpstreamHandler;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

/**
 * 消息分发的字节流处理器
 * @author yuyoo (yuyoo4j@163.com)
 * @date 2009-12-4 下午02:19:41
 */
@ChannelPipelineCoverage("all")
public class MessageDispatchHandler extends SimpleChannelHandler {
	
	private Map<Class<? extends Message>, ChannelDownstreamHandler> downHandlers = new HashMap<Class<? extends Message>, ChannelDownstreamHandler>(100);
	
	private Map<Class<? extends Message>, ChannelUpstreamHandler> upHandlers = new HashMap<Class<? extends Message>, ChannelUpstreamHandler>(100);

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		
		Object obj = e.getMessage();
		if (obj instanceof Message) {
			
			Message msg = (Message)obj;
			ChannelUpstreamHandler handler = upHandlers.get(msg.getClass());
			if (null != handler) {
				handler.handleUpstream(ctx, e);
			} else {
				super.messageReceived(ctx, e);
			}
		} else {
			super.messageReceived(ctx, e);
		}
	}

	@Override
	public void writeRequested(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {

		Object obj = e.getMessage();
		if (obj instanceof Message) {
			
			Message msg = (Message)obj;
			ChannelDownstreamHandler handler = downHandlers.get(msg.getClass());
			if (null != handler) {
				handler.handleDownstream(ctx, e);
			} else {
				super.writeRequested(ctx, e);
			}
		} else {
			super.writeRequested(ctx, e);
		}	
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
			throws Exception {

		// super.exceptionCaught(ctx, e);
	}
	
	/**
	 * 增加向上流转消息的消息处理器
	 * @param msgClazz -- 消息的类型(消息的Class对象)
	 * @param handler -- 消息处理器
	 */
	public void addUpMessageHandler(Class<? extends Message> msgClazz, ChannelUpstreamHandler handler) {
		
		MessageType.registry(msgClazz);
		upHandlers.put(msgClazz, handler);
	}

	/**
	 * 移除向上流转消息的消息处理器
	 * @param msgClazz -- 消息的类型(消息的Class对象)
	 * @return -- 消息处理器
	 */
	public ChannelUpstreamHandler removeUpMessageHandler(Class<? extends Message> msgClazz) {
		
		return upHandlers.remove(msgClazz);
	}
	
	/**
	 * 增加向下流转消息的消息处理器
	 * @param msgClazz -- 消息的类型(消息的Class对象)
	 * @param handler -- 消息处理器
	 */
	public void addDownMessageHandler(Class<? extends Message> msgClazz, ChannelDownstreamHandler handler) {
		
		MessageType.registry(msgClazz);
		downHandlers.put(msgClazz, handler);
	}
	
	/**
	 * 移除向下流转消息的消息处理器
	 * @param msgClazz -- 消息的类型(消息的Class对象)
	 * @return -- 消息处理器
	 */
	public ChannelDownstreamHandler removeDownMessageHandler(Class<? extends Message> msgClazz) {
		
		return downHandlers.remove(msgClazz);
	}
}
